<?php

Raise::load('core.RaiseStaticClass');
Raise::load('core.RaiseHtmlDocType');
Raise::load('core.RaiseHtmlTag');
Raise::load('core.RaiseCollection');
Raise::load('core.RaiseText');

/**
 * RaiseHtml helper class
 * Helps to create HTML and XHTML tags
 *
 * @author Sam-Mauris Yong <hellclanner at live dot com>
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package Raise.Core.DOM
 * @since 1.2
 */
class RaiseHtml extends RaiseStaticClass {

    /**
     * The currently selected document type
     * @var string String constant from RaiseHtmlDocType by default
     * @static
     */
    public static $selectedDocType = RaiseHtmlDocType::XHTML1_1;

    /**
     * Create a RaiseHtmlTag
     * @param string $tagName The HTML tag name
     * @param string $value The content/value of the HTML tag
     * @param array|RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function tag($tagName, $value = '', $attributes = array()){
        $tag = new RaiseHtmlTag($tagName, $value, $attributes);
        return $tag;
    }

    /**
     * Create a hyperlink HTML tag &lt;a>
     * @param string $text The text of the HTML tag
     * @param string|Url $url The URL of the hyperlink
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     */
    public static function hyperlink($text, $url, $attributes = array()){
        $attributes = new RaiseCollection($attributes);
        $attributes->add('href', $url);
        return self::tag('a', $text, $attributes);
    }

    /**
     * Create a breakline HTML tag &lt;br /&gt;
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     */
    public static function breakLine($attributes = array()){
        return self::tag('br', '', $attributes);
    }

    /**
     * Create a script block HTML tag &lt;script>
     * @param string $code The Javascript code
     * @param RaiseCollection $attributes Attributes of the HTML tag
     * @return RaiseHtmlTag
     */
    public static function script($code, $attributes = array()){
        if(self::isXHTMLSelected() && strpos($code, '<![CDATA[') === false){
            $code = '/* <![CDATA[ */ ' . $code . ' /* ]]> */';
        }
        return self::tag('script', $code, $attributes);
    }


    /**
     * Create a hyperlink HTML tag &lt;script src="...">
     * @param string $src The Javascript file to include
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     */
    public static function scriptFile($src, $attributes = array()){
        $attributes = new RaiseCollection($attributes);
        $attributes->add('src', $src);
        return self::tag('script', '', $attributes);
    }

    /**
     * Create a hyperlink HTML tag &lt;title>
     * @param string $title
     * @return RaiseHtmlTag
     */
    public static function title($title){
        return self::tag('title', RaiseHtml::encode($title));
    }

    /**
     * Create a section HTML tag &lt;div>
     * @param string $content Content of the HTML div tag
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     */
    public static function div($content, $attributes = array()){
        return self::tag('div', $content, $attributes);
    }

    /**
     * Create a spanning label HTML tag &lt;span>
     * @param string $content Content of the HTML span tag
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     */
    public static function span($content, $attributes = array())
    {
        return self::tag('span', $content, $attributes);
    }
    /**
     * Create a style block HTML tag &lt;style>
     * @param string $style CSS Codes
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     */
    public static function css($style, $attributes = array()){
        return self::tag('style', $style, $attributes);
    }

    /**
     * Create an image HTML tag &lt;img>
     * @param string $src The image file URL
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     */
    public static function image($src, $attributes = array()){
        $attributes = new RaiseCollection($attributes);
        $attributes->add('src', $src);
        return self::tag('img', '', $attributes);
    }

    /**
     * Create a preformat HTML tag &lt;pre>
     * @param string $content The content of the preformat block
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     */
    public static function preformat($content, $attributes = array()){
        return self::tag('pre', $content, $attributes);
    }
    
    /**
     * Convert all characters with special significance in HTML to their respective HTML entities in a string.
     * @param string|RaiseString $s The string to encode
     * @return string
     * @link http://php.net/htmlspecialchars
     */
    public static function encode($s){
        return htmlspecialchars($s, ENT_QUOTES, 'UTF-8', false);
    }
    
    /**
     * Convert special HTML entities back to characters
     * @param string|RaiseString $s The string to decode
     * @return string
     * @link http://php.net/htmlspecialchars-decode
     */
    public static function decode($s){
        return htmlspecialchars_decode($s, ENT_QUOTES);
    }

    /**
     * Determine whether the selected doctype is XHTML or not
     * @return boolean
     */
    public static function isXHTMLSelected(){
        switch(self::$selectedDocType){
            case RaiseHtmlDocType::XHTML1_1:
            case RaiseHtmlDocType::XHTML_BASIC_1_1:
            case RaiseHtmlDocType::XHTML1_STRICT:
            case RaiseHtmlDocType::XHTML1_TRANSITIONAL:
            case RaiseHtmlDocType::XHTML1_FRAMESET:
                return true;
        }
        return false;
    }

    /**
     * Determine whether the selected doctype is HTML or not
     * @return boolean
     */
    public static function isHTMLSelected(){
        switch(self::$selectedDocType){
            case RaiseHtmlDocType::HTML4_01_STRICT:
            case RaiseHtmlDocType::HTML4_01_TRANSITIONAL:
            case RaiseHtmlDocType::HTML4_01_FRAMSET:
            case RaiseHtmlDocType::HTML5:
                return true;
        }
        return false;
    }
}
